#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>


#define NL_SET 0x11

#define MAXPALOAD 64

static int nl_send(int fd, struct sockaddr_nl *sock, __u16 type,
                   const void *buf, size_t count)
{
    int tot_len = NLMSG_SPACE(count);
    unsigned char data[tot_len];

    struct nlmsghdr *nlh = (struct nlmsghdr *)data;

    nlh->nlmsg_len = tot_len;
    nlh->nlmsg_type = type;
    nlh->nlmsg_flags = NLM_F_REQUEST;
    nlh->nlmsg_seq = 0;
    nlh->nlmsg_pid = getpid();

    memcpy(NLMSG_DATA(nlh), buf, count);

    return sendto(fd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)sock,
                  sizeof(*sock));
}

static int nl_recv(int fd, struct sockaddr_nl *sock, void *buf, size_t count)
{
    int len;
    char tmp[count + NLMSG_HDRLEN];
    socklen_t socklen = sizeof(struct sockaddr_nl);
    int msg_len;

    len = recvfrom(fd, tmp, sizeof(tmp), 0, (struct sockaddr *)sock, &socklen);
    if (len < 0) {
        perror("recvfrom()");
        return -1;
    }


    // 解析接收到的消息
    struct nlmsghdr *nlh = (struct nlmsghdr *)tmp;


    while (NLMSG_OK(nlh, len)) {
        if (nlh->nlmsg_type == NLMSG_ERROR)
        {
            continue;
        }

        // 复制数据到缓冲区
        memcpy(buf, NLMSG_DATA(nlh), nlh->nlmsg_len - NLMSG_HDRLEN);

        msg_len = nlh->nlmsg_len - NLMSG_HDRLEN;

        // 移动到下一个消息
        nlh = NLMSG_NEXT(nlh, len);
    }

    return msg_len;
}


static short arrayTest[2500] = {0};

#define NETLINK_TEST 29
#define NL_GET 0x10

static int sockfd;
static struct sockaddr_nl kpeer;


int  init_app_netlink()
{
    sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);
    if (sockfd < 0) {
        perror("socket()");
        return -1;
    }

    /* local sock init */
    struct sockaddr_nl local;

    local.nl_family = AF_NETLINK;
    local.nl_pad = 0;
    local.nl_pid = getpid();
    local.nl_groups = 0;


    if (bind(sockfd, (struct sockaddr *)&local, sizeof(local)) < 0) {
        perror("bind()");
        return -1;
    }


    /* kernel peer sock init */


    kpeer.nl_family = AF_NETLINK;
    kpeer.nl_pad = 0;
    kpeer.nl_pid = 0;
    kpeer.nl_groups = 0;

    char data[10] = {0};

    if (nl_send(sockfd, &kpeer, NL_GET, data, sizeof(data)) < 0)
        return -1;

    return 0;
}

int main()
{
    int ret = -1;

    printf("[%s][%d] =============1639 \r\n", __func__, __LINE__);


    ret = init_app_netlink();
    if(ret < 0)
    {
        return -1;
    }
   

   /** **/
    while (1) {
 printf("[%s][%d] =============1639 \r\n", __func__, __LINE__);

        int len = nl_recv(sockfd, &kpeer, arrayTest, sizeof(arrayTest));
 printf("[%s][%d] =============1639 \r\n", __func__, __LINE__);

        printf("[%s][%d] app recieved len = %u \r\n", __func__, __LINE__, len);
        if (len <= 0)
            return 1;

	for (int i = 0; i < len/sizeof(short); ++i) {
		printf("%d ", arrayTest[i]);
		if ((i + 1) % 10 == 0) {  // 每10个数字换行
		    printf("\n");
		}
	    }
    }

    return 0;
}


